/* -*- c++ -*- */
/*
 * This file is part of the SD Project.
 *
 * Authors: Cleiber Marques da Silva <cleiber@lisha.ufsc.br>
 * 			Odilson Tadeu Valle <odilson@sj.ifsc.edu.br>
 * 
 * SD Project is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; version 2 of the License.
 */

#include <iostream>

#include "recv.h"

namespace sd {
	recv::recv(std::string _id)
	{
		id = _id;
	}

	void recv::find_recv(int argc, char **argv)
	{
		try {
			CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);

			CORBA::Object_var obj = getObjectReference(orb, id.c_str());

			listener_ref = listener::_narrow(obj);

			//orb->destroy();
		}
		catch(CORBA::TRANSIENT&) {
			std::cerr << "Caught system exception TRANSIENT -- unable to contact the "
			<< "server." << std::endl;
		}
		catch(CORBA::SystemException& ex) {
			std::cerr << "Caught a CORBA::" << ex._name() << std::endl;
		}
		catch(CORBA::Exception& ex) {
			std::cerr << "Caught CORBA::Exception: " << ex._name() << std::endl;
		}
		catch(omniORB::fatalException& fe) {
			std::cerr << "Caught omniORB::fatalException:" << std::endl;
			std::cerr << "  file: " << fe.file() << std::endl;
			std::cerr << "  line: " << fe.line() << std::endl;
			std::cerr << "  mesg: " << fe.errmsg() << std::endl;
		}
	}

	CORBA::Object_ptr recv::getObjectReference(CORBA::ORB_ptr orb, const char *id)
	{
		CosNaming::NamingContext_var rootContext;
  
		try {
			// Obtain a reference to the root context of the Name service:
			CORBA::Object_var obj;
			obj = orb->resolve_initial_references("NameService");

			// Narrow the reference returned.
			rootContext = CosNaming::NamingContext::_narrow(obj);
			if (CORBA::is_nil(rootContext)) {
				std::cerr << "Failed to narrow the root naming context." << std::endl;
				return CORBA::Object::_nil();
		    }
		}
		catch (CORBA::NO_RESOURCES&) {
			std::cerr << "Caught NO_RESOURCES exception. You must configure omniORB "
			<< "with the location" << std::endl
			<< "of the naming service." << std::endl;
			return 0;
		}
		catch(CORBA::ORB::InvalidName& ex) {
			// This should not happen!
			std::cerr << "Service required is invalid [does not exist]." << std::endl;
			return CORBA::Object::_nil();
		}

		// Create a name object, containing the name test/context:
		CosNaming::Name name;
		name.length(1);

		name[0].id   = CORBA::string_dup(id);

		try {
			// Resolve the name to an object reference.
			return rootContext->resolve(name);
		}
		catch(CosNaming::NamingContext::NotFound& ex) {
		// This exception is thrown if any of the components of the
		// path [contexts or the object] aren't found:
		std::cerr << "Context not found." << std::endl;
		}
		catch(CORBA::TRANSIENT& ex) {
		std::cerr << "Caught system exception TRANSIENT -- unable to contact the "
        	 << "naming service." << std::endl
		<< "Make sure the naming server is running and that omniORB is "
		<< "configured correctly." << std::endl;
		}
		catch(CORBA::SystemException& ex) {
			std::cerr << "Caught a CORBA::" << ex._name()
			<< " while using the naming service." << std::endl;
			return 0;
		}

		return CORBA::Object::_nil();
	}
}
